#include "../coredef.h"
#include "cppdef.h"


#define	IFSTAT_DONE			2
#define	cCONNECT_LEFT		1
#define	cCONNECT_RIGHT		2

#define CPPIF_LONG_MAX		2147483647L
#define CPPIF_LONG_MIN		-2147483647L
#define CPPIF_ULONG_MAX		4294967295UL

typedef struct _CPPVALUE
{
	S4		lVal;
	U4		ulVal;
	DOUBLE		dbVal;
} CPPVALUE;
static const struct	_ESCAPECHAR
{
	UCHAR	uchSrc;
	UCHAR	uchDst;
} stEscapeChar[] =
{
	{ 'a',	'\a'	},
	{ 'b',	'\b'	},
	{ 'f',	'\f'	},
	{ 'n',	'\n'	},
	{ 'r',	'\r'	},
	{ 't',	'\t'	},
	{ 'v',	'\v'	},
	{ '\\',	'\\'	},
	{ '\'',	'\''	},
	{ '"',	'"'		},
	{ '?',	'\?'	},
	{ '\0',	'\0'	}
};

typedef struct _CALCCODE      /* 各运算符的优先级 */
{
	U2	usKind;			/* 演算種別(ﾄｰｸﾝｺｰﾄﾞ)	*/
	SCHAR	cRank;			/* 演算子の優先順位	*/
	UCHAR	ucConnect;		/* 演算子の結合法則	*/
} CALCCODE, *PCALCCODE;

static S4 cppIfCalcCollectExp( AST * pastPPCond  )  ;
static BOOL cppIfIsTrueCondition( AST astPPCond ){
	U2 kind = stCorePPConditionAccess.OpKind.get( astPPCond );
	if( kind == xPPTOKEN_DOUBLE ){
		DOUBLE value = stCorePPConditionAccess.dbValue.get( astPPCond );
		if( value == 0. ){
			return FALSE;
		}
	}else if( kind == xPPTOKEN_ULONG ){
		U4 value = stCorePPConditionAccess.u4Value.get( astPPCond );
		if( value == 0 ){
			return FALSE;
		}
	}else{
		S4 value = stCorePPConditionAccess.s4Value.get( astPPCond );
		if( value == 0 ){
			return FALSE;
		}
	}
	return TRUE;
}
static VOID cppIfCopyValue( AST astPPCondOrg, AST astPPCondDst  ){
	U2 kind = stCorePPConditionAccess.OpKind.get( astPPCondOrg );
	stCorePPConditionAccess.OpKind.set( astPPCondDst, kind );
	if( kind == xPPTOKEN_DOUBLE ){
		DOUBLE value = stCorePPConditionAccess.dbValue.get( astPPCondOrg );
		stCorePPConditionAccess.dbValue.set( astPPCondDst, value );
	}else if( kind == xPPTOKEN_ULONG ){
		U4 value = stCorePPConditionAccess.u4Value.get( astPPCondOrg );
		stCorePPConditionAccess.u4Value.set( astPPCondDst, value );
	}else{
		S4 value = stCorePPConditionAccess.s4Value.get( astPPCondOrg );
		stCorePPConditionAccess.s4Value.set( astPPCondDst, value );
	}
}
static U2 cppIfArithKind( U2 kindleft, U2 kindright ){
	if( kindleft == xPPTOKEN_DOUBLE || kindright == xPPTOKEN_DOUBLE ){
		return xPPTOKEN_DOUBLE;
	}
	if( kindleft == xPPTOKEN_ULONG || kindright == xPPTOKEN_ULONG ){
		return xPPTOKEN_ULONG;
	}
	return xPPTOKEN_LONG;
}
static DOUBLE cppIfGetDouble( AST astPPCond ){
	U2 kind = stCorePPConditionAccess.OpKind.get( astPPCond );
	if( kind == xPPTOKEN_DOUBLE ){
		return stCorePPConditionAccess.dbValue.get( astPPCond );
	}else if( kind == xPPTOKEN_ULONG ){
		return (DOUBLE)stCorePPConditionAccess.u4Value.get( astPPCond );
	}
	return (DOUBLE)stCorePPConditionAccess.s4Value.get( astPPCond );
}
static U4 cppIfGetU4( AST astPPCond ){
	U2 kind = stCorePPConditionAccess.OpKind.get( astPPCond );
	if( kind == xPPTOKEN_DOUBLE ){
		return (U4)stCorePPConditionAccess.dbValue.get( astPPCond );
	}else if( kind == xPPTOKEN_ULONG ){
		return (U4)stCorePPConditionAccess.u4Value.get( astPPCond );
	}
	return (U4)stCorePPConditionAccess.s4Value.get( astPPCond );
}
static S4 cppIfGetS4( AST astPPCond ){
	U2 kind = stCorePPConditionAccess.OpKind.get( astPPCond );
	if( kind == xPPTOKEN_DOUBLE ){
		return (S4)stCorePPConditionAccess.dbValue.get( astPPCond );
	}else if( kind == xPPTOKEN_ULONG ){
		return (S4)stCorePPConditionAccess.u4Value.get( astPPCond );
	}
	return (S4)stCorePPConditionAccess.s4Value.get( astPPCond );
}
/************************************************************************/
/* 関 数 名 : 	cppIfGetChar												*/
/* 機    能 :																*/
/* 引 き 数 : 	pszChar														*/
/*			plValue														*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
static S4 cppIfGetChar(PSZ pszIn, S4 *plValue)          /* 解析字符串  */
{
	S4		i;
	BOOL	bFound;
	S4	lTemp;
	PSZ		pszRest;
	PSZ     pszChar = pszIn;
	if (pszChar == NULL || *pszChar == '\0') {
		*plValue = 0;
		return COEXIT_SUCCESS;
	}

	/* '飛ばす、ワイルド文字対応 */
	if (*pszChar == 'L') {
		pszChar ++;
	}
	pszChar ++;

	/* カラ文字定数 */
	if (*pszChar == '\'') {
		*plValue = 0;
		return COEXIT_ERROR;
	}

	if (*pszChar == '\\') {
		pszChar ++;
		bFound = FALSE;
		for (i = 0; stEscapeChar[i].uchSrc != 0; i ++) {
			if (stEscapeChar[i].uchSrc == (*pszChar)) {
				bFound = TRUE;
				break;
			}
		}

		if (bFound == TRUE) {
			lTemp = stEscapeChar[i].uchDst;
			pszChar ++;
		}else if (*pszChar == 'x') {
			pszChar ++;
			lTemp = strtol(pszChar, &pszRest, 16);
			if (errno == ERANGE || lTemp > 0x000000FF) {
				/* エラーコード3301を警告する */
				CppThrowWarning( CC_TOKEN_CHAR_HEX_OVERFLOW,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
						pszIn, NULL );
			}
			pszChar = pszRest;
			lTemp &= 0xFF;
		}else if ((*pszChar) >= '0' && (*pszChar) <= '7') {
			lTemp = strtol(pszChar, &pszRest, 8);
			if (errno == ERANGE || lTemp > 0x000000FF) {
				/* エラーコード3301を警告する */
				CppThrowWarning( CC_TOKEN_CHAR_OCT_OVERFLOW,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
						pszIn, NULL );
			}
			pszChar = pszRest;
			lTemp &= 0xFF;
		}else {
			lTemp = *pszChar;
			pszChar ++;
		}
	}else {
		lTemp = *pszChar;
		pszChar ++;
	}

	/* 終了の'確認 */
	if (*pszChar != '\'' && *pszChar != '\0') {
		/* エラーコード3301を警告する */
		CppThrowWarning( CC_TOKEN_CHAR_MULTICHAR,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
				pszIn, NULL );
	}

	*plValue = lTemp;

	return COEXIT_SUCCESS;
}

static S4 cppIfTryIntNumber(PSZ pszIn, S4 from, S4 to, S4 base, CPPVALUE* pstValue, U2 *pusTokenKind)
{
	U4 result= 0;
	U4 tempResult=0;
	S4 i= from;
	U4 digit=0;
    S4 nUTypeCount =0 ;
    S4 nLTypeCount =0;
    S4 nRet = COEXIT_SUCCESS;
    PSZ pszNumStr = pszIn;
	if (from == to) {
		return COEXIT_ERROR;
	}

	for (; i < to; i++)
	{
		switch( pszNumStr[i] ){
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			digit = pszNumStr[i] -'0';
			break;
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
			digit = pszNumStr[i] - 'a' + 10;
			break;
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
			digit = pszNumStr[i] - 'A' + 10;
			break;
		default:
			digit = base + 1;
			break;
		}
		if( digit >= base ){
			break;
		}
		tempResult = result;
		result= result*base + digit;
		if( tempResult > result )
		{
			CppThrowWarning( CC_TOKEN_NUMBER_OVERFLOW,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
					pszIn, NULL );
			nRet = COEXIT_WARNING;
		}
	}
	for (; i < to; i++) {
		switch(pszNumStr[i]) {
		case 'u' : case 'U':
			nUTypeCount++;
			break;
		case 'l': case 'L':
			nLTypeCount++;
			break;
		default:
			i = to;
			nRet = COEXIT_ERROR;
			break;
		}
	}
	if( nUTypeCount > 1 || nLTypeCount > 2 ){
		return COEXIT_ERROR;
	}
	if( nUTypeCount ){
		pstValue->ulVal = result;
		*pusTokenKind = xPPTOKEN_ULONG;
	}else{
		if( result > S4_MAXVALUE ){
			pstValue->ulVal = result;
			*pusTokenKind = xPPTOKEN_ULONG;
		}else{
			pstValue->lVal = result;
			*pusTokenKind = xPPTOKEN_LONG;
		}
	}
	return nRet;
}
static S4 cppIfTryHexFloatNumber( PSZ pszNumStr, S4 from, S4 to, CPPVALUE* pstValue, U2 *pusTokenKind )
{
	DOUBLE result_value= 0;
	DOUBLE result_franction=0;
	U4  u4_Exponent = 0;
	BOOL hasDot = FALSE;
	BOOL hasMinusSign = FALSE;
	S4 i= from;
	U4 digit=0;
    S4 nFTypeCount =0 ;
    S4 nLTypeCount =0;
    S4 nRet = COEXIT_SUCCESS;
	if (from == to) {
		return COEXIT_ERROR;
	}

	for (; i < to; i++)
	{
		switch( pszNumStr[i] ){
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			digit = pszNumStr[i] -'0';
			break;
		case 'a':
		case 'b':
		case 'c':
		case 'd':
		case 'e':
		case 'f':
			digit = pszNumStr[i] - 'a' + 10;
			break;
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
			digit = pszNumStr[i] - 'A' + 10;
			break;
		case '.':
			hasDot = TRUE;
			break;
		default:
			digit = 20;
			break;
		}
		if( digit >= 16 ){
			break;
		}
		if( hasDot == FALSE ){
			result_value= result_value*16. + digit;
		}else{
			result_franction = result_franction + digit/16;
		}
	}
	result_value += result_franction;
	if( pszNumStr[i] == 'p' || pszNumStr[i] == 'P' ){
		i++;
		if( i < to ){
			if( pszNumStr[i] == '-' )
			{
				hasMinusSign = TRUE;
				i++;
			}else if( pszNumStr[i] == '+'){
				i++;
			}
			u4_Exponent = 0;
			for (; i < to; i++)
			{
				switch( pszNumStr[i] ){
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					digit = pszNumStr[i] -'0';
					break;
				default:
					digit = 11;
					break;
				}
				if( digit >= 10 ){
					break;
				}
				u4_Exponent = u4_Exponent*10 + digit;
			}
			while( u4_Exponent > 0 ){
				if( hasMinusSign ){
					result_value = result_value/2;
				}else{
					result_value = result_value*2;
				}
				u4_Exponent--;
			}
		}
	}
	for (; i < to; i++) {
		switch(pszNumStr[i]) {
		case 'f' : case 'F':
			nFTypeCount++;
			break;
		case 'l': case 'L':
			nLTypeCount++;
			break;
		default:
			nRet = COEXIT_ERROR;
			i = to;
			break;
		}
	}
	if(  nFTypeCount > 1 || nLTypeCount > 1 ){
		return COEXIT_ERROR;
	}
	pstValue->dbVal = result_value;
	*pusTokenKind = xPPTOKEN_DOUBLE;
	return nRet;
}
static S4 cppIfTryFloatNumber( PSZ pszNumStr, S4 from, S4 to, CPPVALUE* pstValue, U2 *pusTokenKind )
{
	DOUBLE result_value= 0;
	DOUBLE result_franction=0;
	DOUBLE tempValue;
	U4  u4_Exponent = 0;
	BOOL hasDot = FALSE;
	BOOL hasMinusSign = FALSE;
	S4 i= from;
	U4 digit=0;
	S4 times = 0;
    S4 nFTypeCount =0 ;
    S4 nLTypeCount =0;
//    S4 nRet = COEXIT_SUCCESS;
	if (from == to) {
		return COEXIT_ERROR;
	}

	for (; i < to; i++)
	{
		switch( pszNumStr[i] ){
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			digit = pszNumStr[i] -'0';
			break;
		case '.':
			if( hasDot == TRUE ){
				return COEXIT_ERROR;
			}
			hasDot = TRUE;
			digit = 0;
			continue;
		default:
			digit = 11;
			break;
		}
		if( digit >= 10 ){
			break;
		}
		if( hasDot == FALSE ){
			result_value= result_value*10. + (DOUBLE)digit;
		}else{
			times++;
			tempValue = (DOUBLE) digit;
			if(times>0){
				digit = times;
				while( digit > 0 ){
					tempValue /= 10.;
					digit--;
				}
			}
			result_franction = result_franction + tempValue;
		}
	}
	result_value += result_franction;
	if( pszNumStr[i] == 'e' || pszNumStr[i] == 'E' ){
		i++;
		if( i < to ){
			if( pszNumStr[i] == '-' )
			{
				hasMinusSign = TRUE;
				i++;
			}else if( pszNumStr[i] == '+'){
				i++;
			}
			u4_Exponent = 0;
			for (; i < to; i++)
			{
				switch( pszNumStr[i] ){
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					digit = pszNumStr[i] -'0';
					break;
				default:
					digit = 11;
					break;
				}
				if( digit >= 10 ){
					break;
				}
				u4_Exponent = u4_Exponent*10 + digit;
			}
			while( u4_Exponent > 0 ){
				if( hasMinusSign ){
					result_value = result_value/10;
				}else{
					result_value = result_value*10;
				}
				u4_Exponent--;
			}
		}
	}
	for (; i < to; i++) {
		switch(pszNumStr[i]) {
		case 'f' : case 'F':
			nFTypeCount++;
			break;
		case 'l': case 'L':
			nLTypeCount++;
			break;
		default:
//			nRet = COEXIT_ERROR;
			i = to;
			break;
		}
	}
	if( nFTypeCount > 1 || nLTypeCount > 1 ){
		return COEXIT_ERROR;
	}
	pstValue->dbVal = result_value;
	*pusTokenKind = xPPTOKEN_DOUBLE;
	return COEXIT_SUCCESS;
}
static S4 cppIfGetFloatNumber(PSZ pszNumStr,CPPVALUE* pstValue, U2 *pusTokenKind)
{

    if (str_length(pszNumStr) > 1) {
    	if (pszNumStr[0] == '0') {
    		switch (pszNumStr[1]) {
    		case 'x':
    		case 'X':
    			return cppIfTryHexFloatNumber( pszNumStr, 2, strlen( pszNumStr ), pstValue, pusTokenKind );
    		}
    	}
    }
	return cppIfTryFloatNumber( pszNumStr, 0, strlen( pszNumStr ), pstValue, pusTokenKind );
}
/************************************************************************/
/* 関 数 名 : 	cppIfGetNumber												*/
/* 機    能 :																*/
/* 引 き 数 : 	pszNumStr													*/
/*			plValue														*/
/*			pusNumKind													*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
static S4 cppIfGetIntNumber(PSZ pszNumStr,CPPVALUE* pstValue, U2 *pusTokenKind)
{
    BOOL isBin = FALSE;
    BOOL isHex = FALSE;
    BOOL isOctal = FALSE;

    if (str_length(pszNumStr) > 1) {
    	if (pszNumStr[0] == '0') {
    		switch (pszNumStr[1]) {
    		case 'b':
    		case 'B':
    			isBin = TRUE;
    			break;
    		case 'x':
    		case 'X':
    			isHex = TRUE;
    			break;
    		case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
    			isOctal = TRUE;
    			break;
    		}
    	}
    }
    if (isBin) {
    	return cppIfTryIntNumber( pszNumStr, 2, strlen( pszNumStr ), 2, pstValue, pusTokenKind );
    }
    if (isHex) {
    	return cppIfTryIntNumber( pszNumStr, 2, strlen( pszNumStr ), 16, pstValue, pusTokenKind );
    }
    if (isOctal) {
    	return cppIfTryIntNumber( pszNumStr, 1, strlen( pszNumStr ), 8, pstValue, pusTokenKind );
    }
	return cppIfTryIntNumber( pszNumStr, 0, strlen( pszNumStr ), 10, pstValue, pusTokenKind );
}
static S4 cppIfGetNumber(PSZ pszNumStr, CPPVALUE* pstValue, U2 *pusTokenKind)
{
	S4 nRet1;

	nRet1 = cppIfGetIntNumber( pszNumStr, pstValue, pusTokenKind );
	if( nRet1 == COEXIT_SUCCESS ){
		return COEXIT_SUCCESS;
	}
	nRet1 = cppIfGetFloatNumber( pszNumStr, pstValue, pusTokenKind );
	return nRet1;
}

/************************************************************************/
/* 関 数 名 : 	cppIfPrimary												*/
/* 機    能 :																*/
/* 引 き 数 : 	pastUnary			条件式の数値								*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
static S4 cppIfCalcCollectPrimary(AST *pastUnary)               /* 解析 if之后条件式 */
{
	S4 	iRetVal;			/* 戻り値 */
	U2	usTokenKind;		/* 前処理字句種類 */
	AST		astFirstLoc;				/* 位置情報 */
	AST     astSecondLoc;
	AST		astPrm;				/* 単項式情報 */
	AST     astNode = 0;
	PSZ		pszTemp;
	S4	lTemp;
	U2	usNumKind;
	CPPVALUE stValue;

	*pastUnary = 0;

	iRetVal = COEXIT_SUCCESS;
	usTokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );

	switch (usTokenKind) {
		case xPPTOKEN_SYM:
			CppThrowWarning( CPP_CONDEXP_UNDEF_SYMBOL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
			astPrm = stCorePPConditionAccess.getMax();
			astFirstLoc = stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
			stCorePPConditionAccess.locScp.set( astPrm, astFirstLoc );
			stCorePPConditionAccess.nodeKind.set( astPrm, xPPTOKEN_SYM );
			stCorePPConditionAccess.OpKind.set( astPrm, xPPTOKEN_LONG );
			stCorePPConditionAccess.s4Value.set( astPrm, 0 );
			*pastUnary = astPrm;
			iRetVal = CppTokenGetNextToken( TRUE, FALSE);
			break;

		case xPPTOKEN_PPNUM:
			pszTemp = stCppTokenAccess.name.get(CUR_TOKEN_INDEX);
			iRetVal = cppIfGetNumber(pszTemp, &stValue, &usNumKind);
			if (iRetVal != COEXIT_SUCCESS) {
				return (iRetVal);
			}
			FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
			astPrm = stCorePPConditionAccess.getMax();
			astFirstLoc = stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
			stCorePPConditionAccess.locScp.set( astPrm, astFirstLoc );
			stCorePPConditionAccess.nodeKind.set( astPrm, usNumKind );

			if( usNumKind == xPPTOKEN_DOUBLE )
			{
				stCorePPConditionAccess.dbValue.set( astPrm, stValue.dbVal );
				stCorePPConditionAccess.OpKind.set( astPrm, xPPTOKEN_DOUBLE );
			}
			else if( usNumKind == xPPTOKEN_ULONG )
			{
				stCorePPConditionAccess.u4Value.set( astPrm, stValue.ulVal );
				stCorePPConditionAccess.OpKind.set( astPrm, xPPTOKEN_ULONG );
			}else
			{
				stCorePPConditionAccess.s4Value.set( astPrm, stValue.lVal );
				stCorePPConditionAccess.OpKind.set( astPrm, xPPTOKEN_LONG );
			}

			*pastUnary = astPrm;
			iRetVal = CppTokenGetNextToken(TRUE, FALSE);
			break;

		case xPPTOKEN_CHAR:
			pszTemp = stCppTokenAccess.name.get(CUR_TOKEN_INDEX);
			iRetVal = cppIfGetChar(pszTemp, &lTemp);
			if (iRetVal != COEXIT_SUCCESS) {
				return (iRetVal);
			}
			FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
			astPrm = stCorePPConditionAccess.getMax();
			astFirstLoc = stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
			stCorePPConditionAccess.locScp.set( astPrm, astFirstLoc );
			stCorePPConditionAccess.nodeKind.set( astPrm, xPPTOKEN_LONG );
			stCorePPConditionAccess.OpKind.set( astPrm, xPPTOKEN_LONG );
			stCorePPConditionAccess.s4Value.set( astPrm, lTemp );

			*pastUnary = astPrm;
			iRetVal = CppTokenGetNextToken(TRUE, FALSE);
			break;

		case xPPTOKEN_STR:
			/* エラーコード2302を警告する */
			CppThrowWarning( CPP_CONDEXP_TOKEN_ILLEGAL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			iRetVal = CppTokenGetNextToken(TRUE, FALSE);
			return COEXIT_ERROR;

		case xPPTOKEN_HEADER:
			/* エラーコード2302を警告する */
			CppThrowWarning( CPP_CONDEXP_TOKEN_ILLEGAL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			iRetVal = CppTokenGetNextToken(TRUE, FALSE);
			return COEXIT_ERROR;
		case xPPTOKEN_OPENPAREN:
			astFirstLoc = stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
			/* skip operator */
			iRetVal = CppTokenGetNextToken(TRUE, FALSE);
			if (iRetVal != COEXIT_SUCCESS) {
				CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
						stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
				return COEXIT_ERROR;
			}
			/* get middle expression */
			iRetVal = cppIfCalcCollectExp( &astNode);
			if (iRetVal != COEXIT_SUCCESS || astNode == 0 ){
				return iRetVal;
			}
			usTokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
			if (usTokenKind != xPPTOKEN_CLOSEPAREN){
				CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
						stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
				return COEXIT_ERROR;
			}
			FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
			astPrm = stCorePPConditionAccess.getMax();
			astSecondLoc = stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
			astSecondLoc = stCoreCodeScpAccess.mergeCodeScp( astFirstLoc, astSecondLoc );
			stCorePPConditionAccess.locScp.set( astPrm, astSecondLoc );
			stCorePPConditionAccess.nodeKind.set( astPrm, xPPTOKEN_OPENPAREN );
			stCorePPConditionAccess.leftNode.set( astPrm, astNode );
			cppIfCopyValue( astNode, astPrm );
			*pastUnary = astPrm;
			iRetVal = CppTokenGetNextToken(TRUE, FALSE);
			break;
		default:
			CppThrowWarning( CPP_CONDEXP_TOKEN_ILLEGAL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			iRetVal = CppTokenGetNextToken(TRUE, FALSE);
			return COEXIT_ERROR;
	}
	if( iRetVal == COEXIT_FINISHED ) {
		iRetVal = COEXIT_SUCCESS;
	}

	return (iRetVal);
}


/************************************************************************/
/* 関 数 名 : 	cppIfUnary													*/
/* 機    能 :																*/
/* 引 き 数 : 	pastUnary			条件式の構文ツリー							*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
static S4 cppIfCalcCollectUnary(AST *pastUnary)  /* 解析带符号的单项式，如“+1，—1，~1，!1"；"++""--"不能出现在预处理语句中 */
{
	S4		iRet;
	AST		astUnary;			/* 演算項情報 */
	S4		iRetVal;			/* 戻り値 */
	AST		astFirstLoc;				/* 位置情報 */
	AST		astSecondLoc;				/* 位置情報 */
	U2	usTokenKind;		/* 前処理字句種類 */
	U2 kind;
	AST		astPrm;				/* 単項式情報 */

	*pastUnary = 0;
	iRetVal = COEXIT_SUCCESS;
	while (iRetVal == COEXIT_SUCCESS) {
		usTokenKind = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);

		switch (usTokenKind) {
			case xPPTOKEN_ADD:
				astFirstLoc = stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
				iRetVal = CppTokenGetNextToken(TRUE, FALSE);
				if (iRetVal != COEXIT_SUCCESS) {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}
				iRet = cppIfCalcCollectUnary(&astUnary);
				if (iRet != COEXIT_SUCCESS) {
					return (iRet);
				}
				if (astUnary == 0) {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}
		        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
		        astPrm = stCorePPConditionAccess.getMax();
		        astSecondLoc = stCorePPConditionAccess.locScp.get( astUnary );
		        astSecondLoc = stCoreCodeScpAccess.mergeCodeScp( astFirstLoc, astSecondLoc );
		        stCorePPConditionAccess.locScp.set( astPrm, astSecondLoc );
		        stCorePPConditionAccess.leftNode.set( astPrm, astUnary );
		        stCorePPConditionAccess.nodeKind.set( astPrm, xPPTOKEN_PLUS );
		        cppIfCopyValue( astUnary, astPrm );
				*pastUnary = astPrm;
				break;

			case xPPTOKEN_SUB:
				astFirstLoc = stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
				iRetVal = CppTokenGetNextToken(TRUE,FALSE);
				if (iRetVal != COEXIT_SUCCESS) {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}
				iRet = cppIfCalcCollectUnary(&astUnary);
				if (iRet != COEXIT_SUCCESS) {
					return (iRet);
				}
				if (astUnary == 0) {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}
		        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
		        astPrm = stCorePPConditionAccess.getMax();
		        astSecondLoc = stCorePPConditionAccess.locScp.get( astUnary );
		        astSecondLoc = stCoreCodeScpAccess.mergeCodeScp( astFirstLoc, astSecondLoc );
		        stCorePPConditionAccess.locScp.set( astPrm, astSecondLoc );
		        stCorePPConditionAccess.leftNode.set( astPrm, astUnary );
		        stCorePPConditionAccess.nodeKind.set( astPrm, xPPTOKEN_MINUS );
		    	kind = stCorePPConditionAccess.OpKind.get( astUnary );
		    	stCorePPConditionAccess.OpKind.set( astPrm, kind );
		    	if( kind == xPPTOKEN_DOUBLE ){
		    		DOUBLE value = stCorePPConditionAccess.dbValue.get( astUnary );
		    		stCorePPConditionAccess.dbValue.set( astPrm, -value );
		    	}else if( kind == xPPTOKEN_ULONG ){
		    		U4 value = stCorePPConditionAccess.u4Value.get( astUnary );
		    		stCorePPConditionAccess.u4Value.set( astPrm, U4_MAXVALUE-value+1 );
		    	}else{
		    		S4 value = stCorePPConditionAccess.s4Value.get( astUnary );
		    		stCorePPConditionAccess.s4Value.set( astPrm, -value );
		    	}
				*pastUnary = astPrm;
				break;

			case xPPTOKEN_NEG:
				astFirstLoc = stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
				iRetVal = CppTokenGetNextToken(TRUE,FALSE);
				if (iRetVal != COEXIT_SUCCESS) {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}
				iRet = cppIfCalcCollectUnary(&astUnary);
				if (iRet != COEXIT_SUCCESS) {
					return (iRet);
				}
				if (astUnary == 0) {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}
		        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
		        astPrm = stCorePPConditionAccess.getMax();
		        astSecondLoc = stCorePPConditionAccess.locScp.get( astUnary );
		        astSecondLoc = stCoreCodeScpAccess.mergeCodeScp( astFirstLoc, astSecondLoc );
		        stCorePPConditionAccess.locScp.set( astPrm, astSecondLoc );
		        stCorePPConditionAccess.leftNode.set( astPrm, astUnary );
		        stCorePPConditionAccess.nodeKind.set( astPrm, xPPTOKEN_NEG );
		    	kind = stCorePPConditionAccess.OpKind.get( astUnary );
		    	stCorePPConditionAccess.OpKind.set( astPrm, kind );
		    	if( kind == xPPTOKEN_DOUBLE ){
					CppThrowWarning( CPP_CONDEXP_TYPE_ILLEGAL,
							stCorePPConditionAccess.locScp.get( astPrm  ),
							NULL, NULL );
					return COEXIT_ERROR;
		    	}else if( kind == xPPTOKEN_ULONG ){
		    		U4 value = stCorePPConditionAccess.u4Value.get( astUnary );
		    		stCorePPConditionAccess.u4Value.set( astPrm, ~value );
		    	}else{
		    		S4 value = stCorePPConditionAccess.s4Value.get( astUnary );
		    		stCorePPConditionAccess.s4Value.set( astPrm, ~value );
		    	}
				*pastUnary = astPrm;
				break;

			case xPPTOKEN_NOT:
				astFirstLoc = stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX );
				iRetVal = CppTokenGetNextToken(TRUE,FALSE);
				if (iRetVal != COEXIT_SUCCESS) {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}
				iRet = cppIfCalcCollectUnary(&astUnary);
				if (iRet != COEXIT_SUCCESS) {
					return (iRet);
				}
				if (astUnary == 0) {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}
		        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
		        astPrm = stCorePPConditionAccess.getMax();
		        astSecondLoc = stCorePPConditionAccess.locScp.get( astUnary );
		        astSecondLoc = stCoreCodeScpAccess.mergeCodeScp( astFirstLoc, astSecondLoc );
		        stCorePPConditionAccess.locScp.set( astPrm, astSecondLoc );
		        stCorePPConditionAccess.leftNode.set( astPrm, astUnary );
		        stCorePPConditionAccess.nodeKind.set( astPrm, xPPTOKEN_NOT );
		    	stCorePPConditionAccess.OpKind.set( astPrm, xPPTOKEN_LONG );
		    	if( cppIfIsTrueCondition ( astUnary )){
		    		stCorePPConditionAccess.s4Value.set( astPrm, 0 );
		    	}else{
		    		stCorePPConditionAccess.s4Value.set( astPrm, 1 );
		    	}
				*pastUnary = astPrm;
				break;
			case xPPTOKEN_MUL:
			case xPPTOKEN_AND:
			case xPPTOKEN_INC:
			case xPPTOKEN_DEC:
				CppThrowWarning( CPP_CONDEXP_TOKEN_ILLEGAL,
						stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
						stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
				return COEXIT_ERROR;
			default:
				iRet = cppIfCalcCollectPrimary(pastUnary);
				if (iRet != COEXIT_SUCCESS) {
					return (iRet);
				}
				break;
		}
		break;
	}

	return ( iRetVal);
}
/************************************************************************/
static S4 cppIfCalcCollectMultiExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	U2 leftKind;
	U2 rightKind;
	AST astMulti;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectUnary( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_MUL || tokenKind == xPPTOKEN_DIV || tokenKind == xPPTOKEN_MOD ) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectUnary( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astMulti = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astMulti, astLeft );
        stCorePPConditionAccess.rightNode.set( astMulti, astRight );
        stCorePPConditionAccess.nodeKind.set( astMulti, tokenKind );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astMulti, firstScp );

        leftKind = stCorePPConditionAccess.OpKind.get( astLeft );
        rightKind = stCorePPConditionAccess.OpKind.get( astRight );
        leftKind = cppIfArithKind( leftKind, rightKind );
        if( leftKind == xPPTOKEN_DOUBLE ){
        	DOUBLE leftvalue = cppIfGetDouble( astLeft );
        	DOUBLE rightvalue = cppIfGetDouble( astRight );
        	switch( tokenKind ){
        	case xPPTOKEN_MUL:
        		leftvalue = leftvalue * rightvalue;
        		break;
        	case xPPTOKEN_DIV:
        		if(rightvalue ){
        			leftvalue = leftvalue/rightvalue;
        		}else{
        			leftvalue = 0;
        		}
        		break;
        	default:
        		return COEXIT_ERROR;
        	}
        	stCorePPConditionAccess.OpKind.set( astMulti, xPPTOKEN_DOUBLE );
        	stCorePPConditionAccess.dbValue.set( astMulti, leftvalue );
        }else if( leftKind == xPPTOKEN_ULONG ){
        	U4 leftvalue = cppIfGetU4( astLeft );
        	U4 rightvalue = cppIfGetU4( astRight );
        	switch( tokenKind ){
        	case xPPTOKEN_MUL:
        		leftvalue = leftvalue * rightvalue;
        		break;
        	case xPPTOKEN_DIV:
        		if(rightvalue ){
        			leftvalue = leftvalue/rightvalue;
        		}else{
        			leftvalue = 0;
        		}
        		break;
        	default:
           		if(rightvalue ){
					leftvalue = leftvalue%rightvalue;
				}else{
					leftvalue = 0;
				}
				break;
        	}
        	stCorePPConditionAccess.OpKind.set( astMulti, xPPTOKEN_ULONG );
        	stCorePPConditionAccess.u4Value.set( astMulti, leftvalue );
        }else{
        	S4 leftvalue = cppIfGetS4( astLeft );
        	S4 rightvalue = cppIfGetS4( astRight );
        	switch( tokenKind ){
        	case xPPTOKEN_MUL:
        		leftvalue = leftvalue * rightvalue;
        		break;
        	case xPPTOKEN_DIV:
        		if(rightvalue ){
        			leftvalue = leftvalue/rightvalue;
        		}else{
        			leftvalue = 0;
        		}
        		break;
        	default:
           		if(rightvalue ){
					leftvalue = leftvalue%rightvalue;
				}else{
					leftvalue = 0;
				}
				break;
        	}
        	stCorePPConditionAccess.OpKind.set( astMulti, xPPTOKEN_LONG );
        	stCorePPConditionAccess.s4Value.set( astMulti, leftvalue );
        }

        astLeft = astMulti;
        *pastPPCond = astLeft;
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectAddExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	U2 leftKind;
	U2 rightKind;
	AST astAdd;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectMultiExp( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    /* skip space */
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_ADD || tokenKind == xPPTOKEN_SUB ) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectMultiExp( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astAdd = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astAdd, astLeft );
        stCorePPConditionAccess.rightNode.set( astAdd, astRight );
        stCorePPConditionAccess.nodeKind.set( astAdd, tokenKind );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astAdd, firstScp );

        leftKind = stCorePPConditionAccess.OpKind.get( astLeft );
        rightKind = stCorePPConditionAccess.OpKind.get( astRight );
        leftKind = cppIfArithKind( leftKind, rightKind );
        if( leftKind == xPPTOKEN_DOUBLE ){
        	DOUBLE leftvalue = cppIfGetDouble( astLeft );
        	DOUBLE rightvalue = cppIfGetDouble( astRight );
        	switch( tokenKind ){
        	case xPPTOKEN_ADD:
        		leftvalue = leftvalue + rightvalue;
        		break;
        	default:
        		leftvalue = leftvalue - rightvalue;
        		break;
        	}
        	stCorePPConditionAccess.OpKind.set( astAdd, xPPTOKEN_DOUBLE );
        	stCorePPConditionAccess.dbValue.set( astAdd, leftvalue );
        }else if( leftKind == xPPTOKEN_ULONG ){
        	U4 leftvalue = cppIfGetU4( astLeft );
        	U4 rightvalue = cppIfGetU4( astRight );
        	switch( tokenKind ){
        	case xPPTOKEN_ADD:
        		leftvalue = leftvalue + rightvalue;
        		break;
        	default:
        		leftvalue = leftvalue - rightvalue;
        		break;
        	}
        	stCorePPConditionAccess.OpKind.set( astAdd, xPPTOKEN_ULONG );
        	stCorePPConditionAccess.u4Value.set( astAdd, leftvalue );
        }else{
        	S4 leftvalue = cppIfGetS4( astLeft );
        	S4 rightvalue = cppIfGetS4( astRight );
        	switch( tokenKind ){
        	case xPPTOKEN_ADD:
        		leftvalue = leftvalue + rightvalue;
        		break;
        	default:
        		leftvalue = leftvalue - rightvalue;
        		break;
        	}
        	stCorePPConditionAccess.OpKind.set( astAdd, xPPTOKEN_LONG );
        	stCorePPConditionAccess.s4Value.set( astAdd, leftvalue );
        }

        astLeft = astAdd;
        *pastPPCond = astLeft;
        /* skip space */
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectShiftExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	U2 leftKind;
	U2 rightKind;
	AST astShift;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectAddExp( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_LSHT || tokenKind == xPPTOKEN_RSHT) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectAddExp( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astShift = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astShift, astLeft );
        stCorePPConditionAccess.rightNode.set( astShift, astRight );
        stCorePPConditionAccess.nodeKind.set( astShift, tokenKind );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astShift, firstScp );
        leftKind = stCorePPConditionAccess.OpKind.get( astLeft );
        rightKind = stCorePPConditionAccess.OpKind.get( astRight );
        leftKind = cppIfArithKind( leftKind, rightKind );
        if( leftKind == xPPTOKEN_DOUBLE ){
        	return COEXIT_ERROR;
        }else if( leftKind == xPPTOKEN_ULONG ){
        	U4 leftvalue = cppIfGetU4( astLeft );
        	U4 rightvalue = cppIfGetU4( astRight );
        	switch( tokenKind ){
        	case xPPTOKEN_LSHT:
        		leftvalue = leftvalue << rightvalue;
        		break;
        	default:
        		leftvalue = leftvalue >> rightvalue;
        		break;
        	}
        	stCorePPConditionAccess.OpKind.set( astShift, xPPTOKEN_ULONG );
        	stCorePPConditionAccess.u4Value.set( astShift, leftvalue );
        }else{
        	S4 leftvalue = cppIfGetS4( astLeft );
        	S4 rightvalue = cppIfGetS4( astRight );
        	switch( tokenKind ){
        	case xPPTOKEN_LSHT:
        		leftvalue = leftvalue << rightvalue;
        		break;
        	default:
        		leftvalue = leftvalue >> rightvalue;
        		break;
        	}
        	stCorePPConditionAccess.OpKind.set( astShift, xPPTOKEN_LONG );
        	stCorePPConditionAccess.s4Value.set( astShift, leftvalue );
        }
        astLeft = astShift;
        *pastPPCond = astLeft;
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectRelationalExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	U2 leftKind;
	U2 rightKind;
	AST astRelation;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectShiftExp( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_LESS || tokenKind == xPPTOKEN_LESSEQU
    		|| tokenKind == xPPTOKEN_MORE || tokenKind == xPPTOKEN_MOREEQU) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectShiftExp( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astRelation = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astRelation, astLeft );
        stCorePPConditionAccess.rightNode.set( astRelation, astRight );
        stCorePPConditionAccess.nodeKind.set( astRelation, tokenKind );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astRelation, firstScp );

        leftKind = stCorePPConditionAccess.OpKind.get( astLeft );
         rightKind = stCorePPConditionAccess.OpKind.get( astRight );
         leftKind = cppIfArithKind( leftKind, rightKind );
         if( leftKind == xPPTOKEN_DOUBLE ){
          	DOUBLE leftvalue = cppIfGetDouble( astLeft );
          	DOUBLE rightvalue = cppIfGetDouble( astRight );
          	switch( tokenKind ){
          	case xPPTOKEN_LESS:
          		leftvalue = leftvalue < rightvalue;
          		break;
          	case xPPTOKEN_LESSEQU:
          		leftvalue = leftvalue <= rightvalue;
          		break;
          	case xPPTOKEN_MORE:
          		leftvalue = leftvalue > rightvalue;
          		break;
          	default:
          		leftvalue = leftvalue >= rightvalue;
          		break;
          	}
          	stCorePPConditionAccess.OpKind.set( astRelation, xPPTOKEN_LONG );
          	stCorePPConditionAccess.s4Value.set( astRelation, (S4)leftvalue );
         }else if( leftKind == xPPTOKEN_ULONG ){
         	U4 leftvalue = cppIfGetU4( astLeft );
         	U4 rightvalue = cppIfGetU4( astRight );
         	switch( tokenKind ){
          	case xPPTOKEN_LESS:
          		leftvalue = leftvalue < rightvalue;
          		break;
          	case xPPTOKEN_LESSEQU:
          		leftvalue = leftvalue <= rightvalue;
          		break;
          	case xPPTOKEN_MORE:
          		leftvalue = leftvalue > rightvalue;
          		break;
          	default:
          		leftvalue = leftvalue >= rightvalue;
          		break;
         	}
         	stCorePPConditionAccess.OpKind.set( astRelation, xPPTOKEN_LONG );
         	stCorePPConditionAccess.s4Value.set( astRelation, (S4)leftvalue );
         }else{
         	S4 leftvalue = cppIfGetS4( astLeft );
         	S4 rightvalue = cppIfGetS4( astRight );
         	switch( tokenKind ){
          	case xPPTOKEN_LESS:
          		leftvalue = leftvalue < rightvalue;
          		break;
          	case xPPTOKEN_LESSEQU:
          		leftvalue = leftvalue <= rightvalue;
          		break;
          	case xPPTOKEN_MORE:
          		leftvalue = leftvalue > rightvalue;
          		break;
          	default:
          		leftvalue = leftvalue >= rightvalue;
          		break;
         	}
         	stCorePPConditionAccess.OpKind.set( astRelation, xPPTOKEN_LONG );
         	stCorePPConditionAccess.s4Value.set( astRelation, (S4)leftvalue );
         }

        astLeft = astRelation;
        *pastPPCond = astLeft;
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectEqualityExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	U2 leftKind;
	U2 rightKind;
	AST astEqu;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectRelationalExp( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    /* skip space */
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_EQUEQU || tokenKind == xPPTOKEN_NOTEQU) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectRelationalExp( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astEqu = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astEqu, astLeft );
        stCorePPConditionAccess.rightNode.set( astEqu, astRight );
        stCorePPConditionAccess.nodeKind.set( astEqu, tokenKind );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astEqu, firstScp );
         leftKind = stCorePPConditionAccess.OpKind.get( astLeft );
         rightKind = stCorePPConditionAccess.OpKind.get( astRight );
         leftKind = cppIfArithKind( leftKind, rightKind );
         if( leftKind == xPPTOKEN_DOUBLE ){
          	DOUBLE leftvalue = cppIfGetDouble( astLeft );
          	DOUBLE rightvalue = cppIfGetDouble( astRight );
          	switch( tokenKind ){
          	case xPPTOKEN_EQUEQU:
          		leftvalue = leftvalue == rightvalue;
          		break;
          	default:
          		leftvalue = leftvalue != rightvalue;
          		break;
          	}
          	stCorePPConditionAccess.OpKind.set( astEqu, xPPTOKEN_LONG );
          	stCorePPConditionAccess.s4Value.set( astEqu, leftvalue );
         }else if( leftKind == xPPTOKEN_ULONG ){
         	U4 leftvalue = cppIfGetU4( astLeft );
         	U4 rightvalue = cppIfGetU4( astRight );
         	switch( tokenKind ){
          	case xPPTOKEN_EQUEQU:
          		leftvalue = leftvalue == rightvalue;
          		break;
          	default:
          		leftvalue = leftvalue != rightvalue;
          		break;
         	}
         	stCorePPConditionAccess.OpKind.set( astEqu, xPPTOKEN_LONG );
         	stCorePPConditionAccess.s4Value.set( astEqu, leftvalue );
         }else{
         	S4 leftvalue = cppIfGetS4( astLeft );
         	S4 rightvalue = cppIfGetS4( astRight );
         	switch( tokenKind ){
          	case xPPTOKEN_EQUEQU:
          		leftvalue = leftvalue == rightvalue;
          		break;
          	default:
          		leftvalue = leftvalue != rightvalue;
          		break;
         	}
         	stCorePPConditionAccess.OpKind.set( astEqu, xPPTOKEN_LONG );
         	stCorePPConditionAccess.s4Value.set( astEqu, leftvalue );
         }
        astLeft = astEqu;
        *pastPPCond = astLeft;
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectAndExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	U2 leftKind;
	U2 rightKind;
	AST astAnd;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectEqualityExp( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    /* skip space */
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_AND ) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectEqualityExp( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astAnd = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astAnd, astLeft );
        stCorePPConditionAccess.rightNode.set( astAnd, astRight );
        stCorePPConditionAccess.nodeKind.set( astAnd, xPPTOKEN_AND );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astAnd, firstScp );

        leftKind = stCorePPConditionAccess.OpKind.get( astLeft );
         rightKind = stCorePPConditionAccess.OpKind.get( astRight );
         leftKind = cppIfArithKind( leftKind, rightKind );
         if( leftKind == xPPTOKEN_DOUBLE ){
          	return COEXIT_ERROR;
         }else if( leftKind == xPPTOKEN_ULONG ){
         	U4 leftvalue = cppIfGetU4( astLeft );
         	U4 rightvalue = cppIfGetU4( astRight );
         	leftvalue = leftvalue & rightvalue;
         	stCorePPConditionAccess.OpKind.set( astAnd, xPPTOKEN_ULONG );
         	stCorePPConditionAccess.u4Value.set( astAnd, leftvalue );
         }else{
         	S4 leftvalue = cppIfGetS4( astLeft );
         	S4 rightvalue = cppIfGetS4( astRight );
         	leftvalue = leftvalue & rightvalue;
         	stCorePPConditionAccess.OpKind.set( astAnd, xPPTOKEN_LONG );
         	stCorePPConditionAccess.s4Value.set( astAnd, leftvalue );
         }
        astLeft = astAnd;
        *pastPPCond = astLeft;
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectExclusiveOrExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	U2 leftKind;
	U2 rightKind;
	AST astExclusiveOr;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectAndExp( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_XOR ) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectAndExp( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astExclusiveOr = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astExclusiveOr, astLeft );
        stCorePPConditionAccess.rightNode.set( astExclusiveOr, astRight );
        stCorePPConditionAccess.nodeKind.set( astExclusiveOr, xPPTOKEN_XOR );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astExclusiveOr, firstScp );

        leftKind = stCorePPConditionAccess.OpKind.get( astLeft );
         rightKind = stCorePPConditionAccess.OpKind.get( astRight );
         leftKind = cppIfArithKind( leftKind, rightKind );
         if( leftKind == xPPTOKEN_DOUBLE ){
          	return COEXIT_ERROR;
         }else if( leftKind == xPPTOKEN_ULONG ){
         	U4 leftvalue = cppIfGetU4( astLeft );
         	U4 rightvalue = cppIfGetU4( astRight );
         	leftvalue = leftvalue ^ rightvalue;
         	stCorePPConditionAccess.OpKind.set( astExclusiveOr, xPPTOKEN_ULONG );
         	stCorePPConditionAccess.u4Value.set( astExclusiveOr, leftvalue );
         }else{
         	S4 leftvalue = cppIfGetS4( astLeft );
         	S4 rightvalue = cppIfGetS4( astRight );
         	leftvalue = leftvalue ^ rightvalue;
         	stCorePPConditionAccess.OpKind.set( astExclusiveOr, xPPTOKEN_LONG );
         	stCorePPConditionAccess.s4Value.set( astExclusiveOr, leftvalue );
         }

        astLeft = astExclusiveOr;
        *pastPPCond = astLeft;
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectInclusiveOrExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	U2 leftKind;
	U2 rightKind;
	AST astInclusiveOr;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectExclusiveOrExp( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_OR ) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectExclusiveOrExp( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astInclusiveOr = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astInclusiveOr, astLeft );
        stCorePPConditionAccess.rightNode.set( astInclusiveOr, astRight );
        stCorePPConditionAccess.nodeKind.set( astInclusiveOr, xPPTOKEN_OR );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astInclusiveOr, firstScp );

        leftKind = stCorePPConditionAccess.OpKind.get( astLeft );
         rightKind = stCorePPConditionAccess.OpKind.get( astRight );
         leftKind = cppIfArithKind( leftKind, rightKind );
         if( leftKind == xPPTOKEN_DOUBLE ){
          	return COEXIT_ERROR;
         }else if( leftKind == xPPTOKEN_ULONG ){
         	U4 leftvalue = cppIfGetU4( astLeft );
         	U4 rightvalue = cppIfGetU4( astRight );
         	leftvalue = leftvalue | rightvalue;
         	stCorePPConditionAccess.OpKind.set( astInclusiveOr, xPPTOKEN_ULONG );
         	stCorePPConditionAccess.u4Value.set( astInclusiveOr, leftvalue );
         }else{
         	S4 leftvalue = cppIfGetS4( astLeft );
         	S4 rightvalue = cppIfGetS4( astRight );
         	leftvalue = leftvalue | rightvalue;
         	stCorePPConditionAccess.OpKind.set( astInclusiveOr, xPPTOKEN_LONG );
         	stCorePPConditionAccess.s4Value.set( astInclusiveOr, leftvalue );
         }

        astLeft = astInclusiveOr;
        *pastPPCond = astLeft;
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectlogicalAndExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	AST astLogicalAnd;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectInclusiveOrExp( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_ANDAND ) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectInclusiveOrExp( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astLogicalAnd = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astLogicalAnd, astLeft );
        stCorePPConditionAccess.rightNode.set( astLogicalAnd, astRight );
        stCorePPConditionAccess.nodeKind.set( astLogicalAnd, xPPTOKEN_ANDAND );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astLogicalAnd, firstScp );

        if( cppIfIsTrueCondition( astLeft ) && cppIfIsTrueCondition( astRight ) ){
          	stCorePPConditionAccess.OpKind.set( astLogicalAnd, xPPTOKEN_LONG );
          	stCorePPConditionAccess.s4Value.set( astLogicalAnd, 1 );
        }else{
          	stCorePPConditionAccess.OpKind.set( astLogicalAnd, xPPTOKEN_LONG );
          	stCorePPConditionAccess.s4Value.set( astLogicalAnd, 0 );
        }

        astLeft = astLogicalAnd;
        *pastPPCond = astLeft;
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectLogicalOrExp( AST * pastPPCond  )
{
	AST astLeft;
	AST astRight;
	S4 iRet;
	U2 tokenKind;
	AST astLogicalOr;
	AST firstScp;
	AST secondScp;
	/* get left expression */
	iRet = cppIfCalcCollectlogicalAndExp( &astLeft );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    *pastPPCond = astLeft;
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    while ( tokenKind == xPPTOKEN_OROR ) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			return COEXIT_ERROR;
		}
		/* get right expression */
    	iRet = cppIfCalcCollectlogicalAndExp( &astRight );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astLogicalOr = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astLogicalOr, astLeft );
        stCorePPConditionAccess.rightNode.set( astLogicalOr, astRight );
        stCorePPConditionAccess.nodeKind.set( astLogicalOr, xPPTOKEN_OROR );

        firstScp = stCorePPConditionAccess.locScp.get( astLeft );
        secondScp = stCorePPConditionAccess.locScp.get( astRight );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astLogicalOr, firstScp );
        if( cppIfIsTrueCondition( astLeft ) || cppIfIsTrueCondition(astRight) ){
        	stCorePPConditionAccess.OpKind.set( astLogicalOr, xPPTOKEN_LONG );
        	stCorePPConditionAccess.s4Value.set( astLogicalOr, 1 );
        }else
        {
        	stCorePPConditionAccess.OpKind.set( astLogicalOr, xPPTOKEN_LONG );
        	stCorePPConditionAccess.s4Value.set( astLogicalOr, 0 );
        }
        astLeft = astLogicalOr;
        *pastPPCond = astLeft;

        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectCondExp( AST * pastPPCond  )
{
	AST astLeftNode;
	AST astMiddleNode;
	AST astRightNode;
	AST astColon;
	AST astQuestion;
	S4 iRet;
	U2 tokenKind;
	AST firstScp;
	AST secondScp;

	/* get left expression */
	iRet = cppIfCalcCollectLogicalOrExp( &astLeftNode );
    if (iRet != COEXIT_SUCCESS ){
    	return iRet;
    }
    tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
    if ( tokenKind == xPPTOKEN_QUESTION ) {
    	/* skip operator */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			return COEXIT_ERROR;
		}
		/* get middle expression */
    	iRet = cppIfCalcCollectExp( &astMiddleNode);
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );

        if (tokenKind != xPPTOKEN_COLON){
			CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
        	return COEXIT_ERROR;
        }
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			return COEXIT_ERROR;
		}
		/* get right expression */
        iRet = cppIfCalcCollectCondExp( &astRightNode );
        if (iRet != COEXIT_SUCCESS ){
        	return iRet;
        }
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astQuestion = stCorePPConditionAccess.getMax();
        FATAL_ON_FALSE(stCorePPConditionAccess.alloc(1));
        astColon = stCorePPConditionAccess.getMax();
        stCorePPConditionAccess.leftNode.set( astQuestion, astLeftNode );
        stCorePPConditionAccess.rightNode.set( astQuestion, astColon );
        stCorePPConditionAccess.nodeKind.set( astQuestion, xPPTOKEN_QUESTION );

        stCorePPConditionAccess.leftNode.set( astColon, astMiddleNode );
        stCorePPConditionAccess.rightNode.set( astColon, astRightNode );
        stCorePPConditionAccess.nodeKind.set( astColon, xPPTOKEN_COLON );

        firstScp = stCorePPConditionAccess.locScp.get( astMiddleNode );
        secondScp = stCorePPConditionAccess.locScp.get( astRightNode );
        secondScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astColon, secondScp );

        firstScp = stCorePPConditionAccess.locScp.get( astLeftNode );
        firstScp = stCoreCodeScpAccess.mergeCodeScp( firstScp, secondScp );
        stCorePPConditionAccess.locScp.set( astQuestion, firstScp );
        *pastPPCond = astQuestion;

        if( cppIfIsTrueCondition( astLeftNode ) ){
        	cppIfCopyValue( astMiddleNode, astQuestion );
        }else{
        	cppIfCopyValue( astRightNode, astQuestion );
        }
    }else{
    	*pastPPCond = astLeftNode;
    }
    return COEXIT_SUCCESS;
}
/************************************************************************/
static S4 cppIfCalcCollectAssginExp(AST * pastPPCond  )
{
	/* Skip the assignment operator because it cannot be used in const expression. */
	return cppIfCalcCollectCondExp( pastPPCond );
}
/************************************************************************/
static S4 cppIfCalcCollectExp( AST * pastPPCond  )       /* 整体整理 */
{
	/* Skip the comman because it cannot be used in const expression. */
	return cppIfCalcCollectAssginExp( pastPPCond );
}

/************************************************************************/
/* 関 数 名 : 	cppIfCalcStr												*/
/* 機    能 :																*/
/* 引 き 数 : 	usEndPPToken												*/
/*			pastPPCond													*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
static S4 cppIfCalcConstExpression(AST* pastPPCond)
{
	S4		iRet;
	U2 tokenKind;

	if (pastPPCond == NULL) {
		return COEXIT_SUCCESS;
	}
	*pastPPCond = 0;
	tokenKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
	if( tokenKind == xPPTOKEN_HSPACE || tokenKind == xPPTOKEN_VSPACE ){
    	/* skip space */
    	iRet = CppTokenGetNextToken(TRUE,FALSE);
		if (iRet != COEXIT_SUCCESS) {
			CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
					stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
			return COEXIT_ERROR;
		}
	}
	iRet = cppIfCalcCollectExp( pastPPCond );
	if (iRet != COEXIT_SUCCESS) {
		return (iRet);
	}
	return COEXIT_SUCCESS;
}


/************************************************************************/
/* 関 数 名 : 	cppIfCalcReplace											*/
/* 機    能 :																*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
static S4 cppIfCalcReplace(VOID)         /* 宏替换 */
{
	AST		astMaxKind;
	U2	usKind;
	PSZ		pszTokenName;
	S4		iRetVal=COEXIT_SUCCESS;			/* 戻り値 */
	AST		astToken;			/* 前処理字句連番 */
	AST		astMacroDef;		/* マクロ定義情報 */
	S4		iSearchRet;			/* 探し結果 */
	AST		astEndToken;		/* 終了の前処理字句 */
	BOOL	bParenFlag;			/* 括弧フラグ */

	while (iRetVal == COEXIT_SUCCESS) {
		usKind = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
		if (usKind != xPPTOKEN_SYM) {
			iRetVal = CppTokenGetNextToken(TRUE, FALSE);
			continue;

		}else if (ON == stCppTokenAccess.recFlag.get(CUR_TOKEN_INDEX)) {
			iRetVal = CppTokenGetNextToken(TRUE,FALSE);
			continue;

		}else {
			pszTokenName = stCppTokenAccess.name.get(CUR_TOKEN_INDEX);
			if (0 == strcmp(pszTokenName, "defined")) {
				astToken = CUR_TOKEN_INDEX;

				/* 空白を読み飛ばす */
				iRetVal = CppTokenGetNextToken(TRUE,FALSE);
				if (iRetVal != COEXIT_SUCCESS) {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}

				/* 括弧判断 */
				usKind = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
				if (usKind == xPPTOKEN_OPENPAREN) {
					bParenFlag = TRUE;
					iRetVal = CppTokenGetNextToken(TRUE,FALSE);

					if (iRetVal != COEXIT_SUCCESS) {
						CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
								stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
								stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
						return COEXIT_ERROR;
					}
				}else {
					bParenFlag = FALSE;
				}

				/* 内容処理 */
				usKind = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX);
				if (usKind == xPPTOKEN_SYM) {
					pszTokenName = stCppTokenAccess.name.get(CUR_TOKEN_INDEX);
					iSearchRet = CppDefSearchMacro(pszTokenName, &astMacroDef);
					stCppTokenAccess.tokenKind.set(astToken, xPPTOKEN_PPNUM);
					if (iSearchRet == TRUE && astMacroDef != 0) {
						/* 見つけ */
						if (TRUE == stCoreMacroDefInfoAccess.bValid.get(astMacroDef)) {
							stCppTokenAccess.name.set(astToken, "1");
						}else {
							stCppTokenAccess.name.set(astToken, "0");
						}
					}else {

						stCppTokenAccess.name.set(astToken, "0");
					}
				}else {
					CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
							stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
							stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
					return COEXIT_ERROR;
				}

				/* 閉じ括弧処理 */
				if (bParenFlag) {
					iRetVal = CppTokenGetNextToken(TRUE,FALSE);
					if (iRetVal != COEXIT_SUCCESS) {
						CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
								stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
								stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
						return COEXIT_ERROR;
					}
					usKind = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX );
					if (usKind != xPPTOKEN_CLOSEPAREN) {
						CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
								stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
								stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
						return COEXIT_ERROR;
					}
				}

				iRetVal = CppTokenGetNextToken(TRUE,FALSE);
				FATAL_ON_FATAL( CppTokenDeleteTokensBeforeCurr(astToken + 1));
				continue;

			}else {
				/* マクロ展開 */
				iSearchRet = CppDefSearchMacro(pszTokenName, &astMacroDef);
				if (iSearchRet == TRUE && astMacroDef != 0) {
					/* 見つけ */
					if (FALSE == stCoreMacroDefInfoAccess.bValid.get( astMacroDef )) {
						iRetVal = CppTokenGetNextToken(TRUE, FALSE);
						continue;
					}else {
						astEndToken = CppTokenGetLastOne( );
						iRetVal = CppRepTmpNewCtrl(CUR_TOKEN_INDEX, &astEndToken, astMacroDef);
						CppTokenResetLastOne(astEndToken);
						continue;
					}
				}else {
					iRetVal = CppTokenGetNextToken(TRUE, FALSE);
					continue;
				}
			}
		}
	}

	astMaxKind = stCppMcrExtStkAccess.getMax();
	FATAL_ON_FALSE(stCppMcrExtStkAccess.alloc(-astMaxKind));

	if (iRetVal == COEXIT_FINISHED) {
		iRetVal = COEXIT_SUCCESS;
	}

	return (iRetVal);
}


/************************************************************************/
/* 関 数 名 : 	CppEndifMain												*/
/* 機    能 :																*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー							*/
/*			COEXIT_FATAL		致命エラー								*/
/************************************************************************/
S4 CppEndifMain(VOID)
{
//	U2	usTemp;
	S4 	iRetVal;			/* 戻り値 */
	AST		astIfInfo;			/* IF状態情報 */
	AST     astDirInfo;
	iRetVal = COEXIT_SUCCESS;
	/* 前のTRUEFALSESTAT確認 */
	astIfInfo = stCppDirectiveIFGroupAccess.getMax();
	if (astIfInfo <= MIN_ARRAY) {
		/* エラーコード2316を警告する */

		CppThrowWarning( CPP_ENDIF_IF_NOTFOUND,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}

	/* KIND_TRUEFALSESTATから1行を削除する */
	FATAL_ON_FALSE(stCppDirectiveIFGroupAccess.alloc(-1));
	/* テーブルKIND_DIRECTIVEINFOに1行を追加する */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	/* テーブルKIND_DIRECTIVEINFOの追加した行のULONG_DIRECTIVEKIND属性に　CPPDEF_INCを設定する  */
	astDirInfo = stCoreDirectiveInfoAccess.getMax();
	stCoreDirectiveInfoAccess.kind.set(astDirInfo, CPPDEF_ENDIF );
	/* DIRECTIVE追加 */
	/* 位置情報取得し、設定 */
	iRetVal = CppLocSetDirectiveScope(astDirInfo);
	if( iRetVal != COEXIT_SUCCESS )
	{
		return iRetVal;
	}
	/* 後の内容確認 */
	iRetVal = CppTokenGetNextToken(TRUE, FALSE);
//	usTemp = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
	if (iRetVal == COEXIT_SUCCESS ) {
		/* エラーコード3303を警告する */
		CppThrowWarning( CPP_ENDIF_TOKEN_USELESS,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
	}
	if (iRetVal == COEXIT_FINISHED) {
		iRetVal = COEXIT_SUCCESS;
	}

	FATAL_ON_FATAL(CppTokensDelAll());

	return COEXIT_SUCCESS;
}


/************************************************************************/
/* 関 数 名 : 	CppElseMain													*/
/* 機    能 :																*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
S4 CppElseMain(VOID)
{
	U2	usTemp;
	S4 	iRetVal;			/* 戻り値 */
	AST		astIfInfo;			/* IF状態情報 */
	AST		astDirInfo;			/* 前処理命令情報 */
	U2	usCmdKind;			/* 命令種類 */
	iRetVal = COEXIT_SUCCESS;
	/* 先にIFがないとエラー */
	astIfInfo = stCppDirectiveIFGroupAccess.getMax();
	if (astIfInfo <= MIN_ARRAY) {
		/* エラーコード2316を警告する */
		CppThrowWarning( CPP_ELSE_IF_NOTFOUND,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
				NULL, NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}
	usCmdKind = stCppDirectiveIFGroupAccess.kind.get( astIfInfo );
	/* 前の処理種類判断 */
	if (usCmdKind == CPPDEF_ELSE ) {
		CppThrowWarning( CPP_ELSE_DUPLICATE,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
				NULL, NULL );
		astDirInfo = stCppDirectiveIFGroupAccess.directive.get( astIfInfo );
		CppThrowWarning( CPP_ELSE_DUPLICATE1ST,
				stCoreDirectiveInfoAccess.locScope.get( astDirInfo  ),
				NULL, NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}
	stCppDirectiveIFGroupAccess.kind.set( astIfInfo, CPPDEF_ELSE );

	/* DIRECTIVE追加 */
	/* テーブルKIND_DIRECTIVEINFOに1行を追加する */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	/* テーブルKIND_DIRECTIVEINFOの追加した行のULONG_DIRECTIVEKIND属性に　CPPDEF_INCを設定する  */
	astDirInfo = stCoreDirectiveInfoAccess.getMax();
	stCoreDirectiveInfoAccess.kind.set( astDirInfo, CPPDEF_ELSE );
	/* 位置情報取得し、設定 */
	iRetVal = CppLocSetDirectiveScope(astDirInfo);
	if( iRetVal != COEXIT_SUCCESS )
	{
		return iRetVal;
	}
	stCppDirectiveIFGroupAccess.directive.set( astIfInfo, astDirInfo );
	usTemp = stCppDirectiveIFGroupAccess.state.get(astIfInfo);
	if (usTemp != FALSE) {
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, IFSTAT_DONE );
		stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
	}else {
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, TRUE );
		stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, TRUE );
	}

	iRetVal = CppTokenGetNextToken(TRUE,FALSE);
	usTemp = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
	if (iRetVal == COEXIT_SUCCESS ) {
		CppThrowWarning( CPP_ELSE_TOKEN_USELESS,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
	}
	if (iRetVal == COEXIT_FINISHED) {
		iRetVal = COEXIT_SUCCESS;
	}

	FATAL_ON_FATAL(CppTokensDelAll());

	return COEXIT_SUCCESS;
}


/************************************************************************/
/* 関 数 名 : 	CppElifMain													*/
/* 機    能 :																*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
S4 CppElifMain(VOID)
{
	U2	usTemp;
	S4 	iRetVal;			/* 戻り値 */
	AST		astIfInfo;			/* IF状態情報 */
	AST		astDirInfo;			/* 前処理命令情報 */
	U2	usCmdKind;			/* 命令種類 */
	AST		astCurToken;		/* カレント前処理字句 */
	AST		astPPCondition;		/* 前処理条件式 */
	iRetVal = COEXIT_SUCCESS;
	/* 先にIFがないとエラー */
	astIfInfo = stCppDirectiveIFGroupAccess.getMax();
	if (astIfInfo <= MIN_ARRAY) {
		CppThrowWarning( CPP_ELIF_IF_NOTFOUND,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}
	/* 前の処理種類判断 */
	usCmdKind = stCppDirectiveIFGroupAccess.kind.get(astIfInfo);
	if (usCmdKind != CPPDEF_IF && usCmdKind != CPPDEF_IFDEF && usCmdKind != CPPDEF_IFNDEF) {
		CppThrowWarning( CPP_ELIF_IF_NOTFOUND,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}
	usTemp = stCppDirectiveIFGroupAccess.state.get( astIfInfo );

	if (usTemp != FALSE) {
		/* 親はすでにTRUEではない、DONE */
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, IFSTAT_DONE );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_SUCCESS;
	}
	/* テーブルKIND_DIRECTIVEINFOに1行を追加する */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	/* テーブルKIND_DIRECTIVEINFOの追加した行のULONG_DIRECTIVEKIND属性に　CPPDEF_INCを設定する  */
	astDirInfo = stCoreDirectiveInfoAccess.getMax();
	stCoreDirectiveInfoAccess.kind.set(astDirInfo, CPPDEF_ELIF );
	/* DIRECTIVE追加 */
	/* 位置情報取得し、設定 */
	iRetVal = CppLocSetDirectiveScope(astDirInfo);
	if( iRetVal != COEXIT_SUCCESS )
	{
		return iRetVal;
	}
	iRetVal = CppTokenGetNextToken(TRUE, FALSE);
	if( iRetVal == COEXIT_SUCCESS ){
		/*  */
		astCurToken = CUR_TOKEN_INDEX;
		iRetVal = cppIfCalcReplace();
		if (iRetVal != COEXIT_SUCCESS) {
			usTemp = stCppDirectiveIFGroupAccess.state.get( astIfInfo );
			if (usTemp != FALSE) {
				stCppDirectiveIFGroupAccess.state.set( astIfInfo, IFSTAT_DONE );
				stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
			}else {
				stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
				stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
			}
			FATAL_ON_FATAL(CppTokensDelAll());
			return iRetVal;
		}
		iRetVal = CppTokenResetCurrOne(astCurToken);
		if (iRetVal == COEXIT_FINISHED) {
			CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
					stCoreDirectiveInfoAccess.locScope.get( astDirInfo  ),
					stCppTokenAccess.name.get( CUR_TOKEN_INDEX - 1 ), NULL );
			usTemp = stCppDirectiveIFGroupAccess.state.get( astIfInfo );
			if (usTemp != FALSE) {
				stCppDirectiveIFGroupAccess.state.set( astIfInfo, IFSTAT_DONE );
				stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
			}else {
				stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
				stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
			}
			FATAL_ON_FATAL(CppTokensDelAll());
			return COEXIT_ERROR;
		}
		iRetVal = cppIfCalcConstExpression(&astPPCondition);
		if (iRetVal == COEXIT_FATAL) {
			return (COEXIT_FATAL);
		}else if( iRetVal== COEXIT_ERROR )
		{
			astPPCondition = 0;
		}
	}else{
		astPPCondition = 0;
		CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
				stCoreDirectiveInfoAccess.locScope.get( astDirInfo  ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX - 1 ), NULL );
	}
	if (astPPCondition == 0) {
		iRetVal = COEXIT_ERROR;

		stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
		stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
	}else {
		stCoreDirectiveInfoAccess.idx_param.set(astDirInfo, astPPCondition);
		if(cppIfIsTrueCondition( astPPCondition )){
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, TRUE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, TRUE );
		}
	}
	if( iRetVal == COEXIT_FINISHED ){
		iRetVal = COEXIT_SUCCESS;
	}
	FATAL_ON_FATAL(CppTokensDelAll());

	return (iRetVal);
}


/************************************************************************/
/* 関 数 名 : 	CppIfndefMain												*/
/* 機    能 :																*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
S4 CppIfndefMain(VOID)
{
	U2	usTemp;
	AST 	astKindMax;
	S4 	iRetVal;			/* 戻り値 */
	AST		astIfInfo;			/* IF状態情報 */
	AST		astDirInfo;			/* 前処理命令情報 */
	PSZ		pszMacroName;		/* マクロ名 */
	S4		iSearchRet;			/* 探し結果 */
	AST		astMacroDef;		/* マクロ定義情報 */
	iRetVal = COEXIT_SUCCESS;
	astKindMax = stCppDirectiveIFGroupAccess.getMax();
	usTemp = stCppDirectiveIFGroupAccess.state.get( astKindMax );

	/* TRUEFALSESTAT追加 */
	FATAL_ON_FALSE(stCppDirectiveIFGroupAccess.alloc(1));
	astIfInfo = stCppDirectiveIFGroupAccess.getMax();
	stCppDirectiveIFGroupAccess.kind.set(astIfInfo, CPPDEF_IFNDEF);
	if (usTemp != TRUE) {
		/* 親はすでにTRUEではない、DONE */
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, IFSTAT_DONE );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_SUCCESS;
	}
	/* テーブルKIND_DIRECTIVEINFOに1行を追加する */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	/* テーブルKIND_DIRECTIVEINFOの追加した行のULONG_DIRECTIVEKIND属性に　CPPDEF_INCを設定する  */
	astDirInfo = stCoreDirectiveInfoAccess.getMax();
	stCoreDirectiveInfoAccess.kind.set(astDirInfo, CPPDEF_IFNDEF );
	/* 位置情報取得し、設定 */
	iRetVal = CppLocSetDirectiveScope(astDirInfo);
	if( iRetVal != COEXIT_SUCCESS )
	{
		return iRetVal;
	}

	/* 空白を読み飛ばす */
	iRetVal = CppTokenGetNextToken(TRUE,FALSE);
	if (iRetVal == COEXIT_SUCCESS) {
		usTemp = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
		if (usTemp != xPPTOKEN_SYM) {
			CppThrowWarning( CPP_IFNDEF_CONDEXP_FORMAT_ILLEGAL,
					stCoreDirectiveInfoAccess.locScope.get( astDirInfo  ),
					stCppTokenAccess.name.get( CppTokenGetLastNamedToken() ), NULL );
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
			FATAL_ON_FATAL(CppTokensDelAll());
			return COEXIT_ERROR;
		}
	}
	if (iRetVal == COEXIT_FINISHED) {
		CppThrowWarning( CPP_IFNDEF_CONDEXP_FORMAT_ILLEGAL,
				stCoreDirectiveInfoAccess.locScope.get( astDirInfo  ),
				stCppTokenAccess.name.get( CppTokenGetLastNamedToken() ), NULL );
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
		stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}

	pszMacroName = stCppTokenAccess.name.get(CUR_TOKEN_INDEX);
	stCoreDirectiveInfoAccess.str_param.set( astDirInfo, pszMacroName );

	/* 探していこう */
	iSearchRet = CppDefSearchMacro(pszMacroName, &astMacroDef);
	if (iSearchRet == TRUE && astMacroDef != 0) {
		/* あり */
		if (FALSE == stCoreMacroDefInfoAccess.bValid.get( astMacroDef )) {
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, TRUE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, TRUE );
		}else {
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
		}
	}else {
		/* なし */
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, TRUE );
		stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, TRUE );
	}

	/*  */
	iRetVal = CppTokenGetNextToken(TRUE, FALSE);

	usTemp = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
	if (iRetVal == COEXIT_SUCCESS ) {
		CppThrowWarning( CPP_IFNDEF_TOKEN_USELESS,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX - 1 ), NULL );
	}
	if (iRetVal == COEXIT_FINISHED) {
		iRetVal = COEXIT_SUCCESS;
	}

	FATAL_ON_FATAL(CppTokensDelAll());

	return (iRetVal);
}

/************************************************************************/
/* 関 数 名 : 	CppIfdefMain												*/
/* 機    能 :																*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
S4 CppIfdefMain(VOID)
{
	U2	usTemp;
	AST 	astKindMax;
	S4 	iRetVal;			/* 戻り値 */
	AST		astIfInfo;			/* IF状態情報 */
	AST		astDirInfo;			/* 前処理命令情報 */
	PSZ		pszMacroName;		/* マクロ名 */
	S4		iSearchRet;			/* 探し結果 */
	AST		astMacroDef;		/* マクロ定義情報 */
	iRetVal = COEXIT_SUCCESS;

	astKindMax = stCppDirectiveIFGroupAccess.getMax();
	usTemp = stCppDirectiveIFGroupAccess.state.get( astKindMax );

	/* TRUEFALSESTAT追加 */
	FATAL_ON_FALSE(stCppDirectiveIFGroupAccess.alloc(1));
	astIfInfo = stCppDirectiveIFGroupAccess.getMax();
	stCppDirectiveIFGroupAccess.kind.set(astIfInfo, CPPDEF_IFDEF);
	if (usTemp != TRUE) {
		/* 親はすでにTRUEではない、DONE */
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, IFSTAT_DONE );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_SUCCESS;
	}
	/* テーブルKIND_DIRECTIVEINFOに1行を追加する */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	/* テーブルKIND_DIRECTIVEINFOの追加した行のULONG_DIRECTIVEKIND属性に　CPPDEF_INCを設定する  */
	astDirInfo = stCoreDirectiveInfoAccess.getMax();
	stCoreDirectiveInfoAccess.kind.set(astDirInfo, CPPDEF_IFDEF );
	/* 位置情報取得し、設定 */
	iRetVal = CppLocSetDirectiveScope(astDirInfo);
	if( iRetVal != COEXIT_SUCCESS )
	{
		return iRetVal;
	}

	/* 空白を読み飛ばす */
	iRetVal = CppTokenGetNextToken(TRUE, FALSE);
	if (iRetVal == COEXIT_SUCCESS) {
		usTemp = stCppTokenAccess.tokenKind.get( CUR_TOKEN_INDEX );
		if (usTemp != xPPTOKEN_SYM) {
			CppThrowWarning( CPP_IFDEF_CONDEXP_FORMAT_ILLEGAL,
					stCoreDirectiveInfoAccess.locScope.get( astDirInfo  ),
					stCppTokenAccess.name.get( CppTokenGetLastNamedToken() ), NULL );
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
			FATAL_ON_FATAL(CppTokensDelAll());
			return COEXIT_ERROR;
		}
	}
	if (iRetVal == COEXIT_FINISHED) {
		CppThrowWarning( CPP_IFDEF_CONDEXP_FORMAT_ILLEGAL,
				stCoreDirectiveInfoAccess.locScope.get( astDirInfo  ),
				stCppTokenAccess.name.get( CppTokenGetLastNamedToken() ), NULL );
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
		stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_ERROR;
	}

	pszMacroName = stCppTokenAccess.name.get(CUR_TOKEN_INDEX);
	stCoreDirectiveInfoAccess.str_param.set(astDirInfo, pszMacroName);

	/* 探していこう */
	iSearchRet = CppDefSearchMacro(pszMacroName, &astMacroDef);
	if (iSearchRet == TRUE && astMacroDef != 0) {
		/* あり */
		if (FALSE == stCoreMacroDefInfoAccess.bValid.get( astMacroDef )) {
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
		}else {
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, TRUE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, TRUE );
		}
	}else {
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
		stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
	}

	/*  */
	iRetVal = CppTokenGetNextToken(TRUE, FALSE);
	usTemp = stCppTokenAccess.tokenKind.get(CUR_TOKEN_INDEX);
	if (iRetVal == COEXIT_SUCCESS ) {
		CppThrowWarning( CPP_IFDEF_TOKEN_USELESS,
				stCppTokenAccess.codeScp.get( CUR_TOKEN_INDEX  ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX ), NULL );
	}
	if (iRetVal == COEXIT_FINISHED) {
		iRetVal = COEXIT_SUCCESS;
	}

	FATAL_ON_FATAL(CppTokensDelAll());

	return (iRetVal);
}


/************************************************************************/
/* 関 数 名 : 	CppIfMain													*/
/* 機    能 :																*/
/* 引 き 数 : 	なし															*/
/* 戻 り 値 :	COEXIT_SUCCESS		正常終了									*/
/*			COEXIT_WARNING		警告終了									*/
/*			COEXIT_ERROR		コンパイルエラー								*/
/*			COEXIT_FATAL		致命エラー									*/
/************************************************************************/
S4 CppIfMain(VOID)
{
	U2	usTemp;
	AST 	astKindMax;
	S4 	iRetVal;			/* 戻り値 */
	AST		astIfInfo;			/* IF状態情報 */
	AST		astDirInfo;			/* 前処理命令情報 */
	AST		astCurToken;		/* カレント前処理字句 */
	AST		astPPCondition;		/* 前処理条件式 */

	iRetVal = COEXIT_SUCCESS;
	astKindMax = stCppDirectiveIFGroupAccess.getMax();
	usTemp = stCppDirectiveIFGroupAccess.state.get( astKindMax );

	/* TRUEFALSESTAT追加 */
	FATAL_ON_FALSE(stCppDirectiveIFGroupAccess.alloc(1));
	astIfInfo = stCppDirectiveIFGroupAccess.getMax();
	stCppDirectiveIFGroupAccess.kind.set(astIfInfo, CPPDEF_IF);
	if (usTemp != TRUE) {
		/* 親はすでにTRUEではない、DONE */
		stCppDirectiveIFGroupAccess.state.set( astIfInfo, IFSTAT_DONE );
		FATAL_ON_FATAL(CppTokensDelAll());
		return COEXIT_SUCCESS;
	}

	/* テーブルKIND_DIRECTIVEINFOに1行を追加する */
	FATAL_ON_FALSE(stCoreDirectiveInfoAccess.alloc(1));
	/* テーブルKIND_DIRECTIVEINFOの追加した行のULONG_DIRECTIVEKIND属性に　CPPDEF_INCを設定する  */
	astDirInfo = stCoreDirectiveInfoAccess.getMax();
	stCoreDirectiveInfoAccess.kind.set(astDirInfo, CPPDEF_IF );
	/* 位置情報取得し、設定 */
	iRetVal = CppLocSetDirectiveScope(astDirInfo);
	if( iRetVal != COEXIT_SUCCESS )
	{
		return iRetVal;
	}
	iRetVal = CppTokenGetNextToken(TRUE, FALSE);
	if( iRetVal == COEXIT_SUCCESS ){
		/*  */
		astCurToken = CUR_TOKEN_INDEX;
		iRetVal = cppIfCalcReplace();
		if (iRetVal != COEXIT_SUCCESS) {
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
			FATAL_ON_FATAL(CppTokensDelAll());
			return iRetVal;
		}

		/*  */
		iRetVal = CppTokenResetCurrOne(astCurToken);
		if (iRetVal == COEXIT_FINISHED) {
			CppThrowWarning( CPP_IF_NONE_CONDEXP,
					stCoreDirectiveInfoAccess.locScope.get( astDirInfo  ),
					NULL, NULL );
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
			FATAL_ON_FATAL(CppTokensDelAll());
			return COEXIT_ERROR;
		}

		/*  */
		iRetVal = cppIfCalcConstExpression(&astPPCondition);
		if (iRetVal == COEXIT_FATAL) {
			return (COEXIT_FATAL);
		}else if( iRetVal == COEXIT_ERROR )
		{
			astPPCondition = 0;
		}
	}else{
		astPPCondition = 0;
		CppThrowWarning( CPP_CONDEXP_SYNTAX_ILLEGAL,
				stCoreDirectiveInfoAccess.locScope.get( astDirInfo  ),
				stCppTokenAccess.name.get( CUR_TOKEN_INDEX - 1 ), NULL );
	}

	if (astPPCondition == 0) {
		iRetVal = COEXIT_ERROR;

		stCppDirectiveIFGroupAccess.state.set( astIfInfo, FALSE );
		stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, FALSE );
	}else {
		stCoreDirectiveInfoAccess.idx_param.set(astDirInfo, astPPCondition);
		if(cppIfIsTrueCondition( astPPCondition )){
			stCppDirectiveIFGroupAccess.state.set( astIfInfo, TRUE );
			stCoreDirectiveInfoAccess.bool_result.set( astDirInfo, TRUE );
		}
	}

	FATAL_ON_FATAL(CppTokensDelAll());
	if( iRetVal == COEXIT_FINISHED ){
		iRetVal = COEXIT_SUCCESS;
	}
	return (iRetVal);
}

S4  CppIfFileFinished( VOID ){
	AST nKindMax;

	nKindMax = stCppDirectiveIFGroupAccess.getMax();
	while (nKindMax > MIN_ARRAY) {
		switch( stCppDirectiveIFGroupAccess.kind.get(nKindMax) )
		{
		case CPPDEF_IF:
			CppThrowWarning( CPP_IF_ENDIF_NOTFOUND,
					stCoreDirectiveInfoAccess.locScope.get( stCppDirectiveIFGroupAccess.directive.get(nKindMax)  ),
					NULL, NULL );
			break;
		case CPPDEF_IFDEF:
			CppThrowWarning( CPP_IFDEF_ENDIF_NOTFOUND,
					stCoreDirectiveInfoAccess.locScope.get(  stCppDirectiveIFGroupAccess.directive.get(nKindMax) ),
					NULL, NULL );
			break;
		case CPPDEF_IFNDEF:
			CppThrowWarning( CPP_IFNDEF_ENDIF_NOTFOUND,
					stCoreDirectiveInfoAccess.locScope.get(  stCppDirectiveIFGroupAccess.directive.get(nKindMax) ),
					NULL, NULL );
			break;
		}
		nKindMax--;
	}
	nKindMax = stCppDirectiveIFGroupAccess.getMax();
	FATAL_ON_FALSE(stCppDirectiveIFGroupAccess.alloc(MIN_ARRAY-nKindMax));
	return COEXIT_SUCCESS;
}
